/*
 * @Author: xiaosihan 
 * @Date: 2023-12-20 17:10:15 
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2023-12-20 17:59:32
 */


import clsx from "clsx";
import { autorun } from "mobx";
import { ReactNode, useEffect, useRef } from "react";
import Transition from "three-base/Transition";
import styles from "./autoScroll.module.less";
import threeUtils from "three-base/threeUtils";

interface Iprops {
    name?: string,
    intervalTime?: number, // 间隔时间毫秒
    children?: ReactNode,
    className?: string,
    enlable?: boolean,
    onScrolled?: (page: number) => void;
}

// 自动滚动
export default function AutoScroll(props: Iprops) {

    const dom = useRef<HTMLDivElement | null>(null);
    const run = useRef(true);
    const transition = useRef(new Transition({ scrollTop: 0 }));

    transition.current.onChange(({ scrollTop }) => {
        if (dom.current) {
            dom.current.scrollTop = scrollTop;
        }
    });

    // 滚动到下一个
    const scrollNext = async () => {
        if (dom.current) {
            const { scrollTop, scrollHeight, clientHeight } = dom.current;

            const computedStyle = window.getComputedStyle(dom.current);

            // 寻找下一个子元素的相对top的位置
            let i = 0;
            let chrild = dom.current.childNodes[i] as HTMLElement;

            do {
                chrild = dom.current.childNodes[i] as HTMLElement;
                if (chrild) {
                    i++
                }
            } while (chrild && chrild.offsetTop <= (scrollTop + parseFloat(computedStyle.paddingTop || "0")));

            if (props.onScrolled) {
                props.onScrolled(i);
            }

            if (run.current && chrild) {

                await transition.current.set({
                    scrollTop: chrild.offsetTop - parseFloat(computedStyle.paddingTop || "0")
                });

                if (transition.current.get("scrollTop") >= (scrollHeight / 2)) {
                    transition.current.reset({
                        scrollTop: chrild.offsetTop % (scrollHeight / 2)
                    });
                }
            }
        }
    }


    useEffect(() => {
        let startTime = 0;
        const loop = (e: any) => {
            if (startTime === 0) {
                startTime = e.timeTemp;
            }

            if (
                e.timeTemp > (startTime + (props.intervalTime || 3000))
                && run.current
                && [true, undefined].includes(props.enlable)
            ) {
                startTime = e.timeTemp;
                scrollNext(); // 启动滚动
            }
        }
        threeUtils.addEventListener("requestAnimationFrame", loop);
        return () => threeUtils.removeEventListener("requestAnimationFrame", loop);
    }, [props]);

    return (
        <div
            ref={dom}
            onMouseEnter={() => run.current = false}
            onMouseLeave={() => run.current = true}
            className={clsx(props.className, styles.autoScroll)}
            onScroll={() => {
                if (dom.current && !run.current) {
                    transition.current.reset({
                        scrollTop: dom.current.scrollTop
                    });
                }
            }}
        >
            {props.children}
            {props.children}
        </div>
    );

}